home *** CD-ROM | disk | FTP | other *** search
/ Australian Personal Computer 2000 July / CD 3 / redhat-6.2.iso / RedHat / instimage / usr / lib / anaconda / todo.py < prev    next >
Encoding:
Python Source  |  2000-05-02  |  42.6 KB  |  1,358 lines

  1. import rpm, os
  2. rpm.addMacro("_i18ndomains", "redhat-dist");
  3.  
  4. import iutil, isys
  5. from lilo import LiloConfiguration
  6. arch = iutil.getArch ()
  7. if arch == "sparc":
  8.     from silo import SiloInstall
  9. elif arch == "alpha":
  10.     from milo import MiloInstall, onMILO
  11. import string
  12. import socket
  13. import crypt
  14. import whrandom
  15. import pcmcia
  16. import _balkan
  17. import kudzu
  18. from kbd import Keyboard
  19. from simpleconfig import SimpleConfigFile
  20. from mouse import Mouse
  21. from xf86config import XF86Config
  22. import errno
  23. import raid
  24. import fstab
  25. import time
  26. import gettext_rh
  27. from translate import _
  28.  
  29. class LogFile:
  30.     def __init__ (self, serial, reconfigOnly, test):
  31.     if serial or reconfigOnly:
  32.         self.logFile = open("/tmp/install.log", "w")
  33.     elif reconfigOnly:
  34.         self.logFile = open("/tmp/reconfig.log", "w")
  35.     elif test:
  36.         self.logFile = open("/tmp/anaconda-debug.log", "w")
  37.     else:
  38.         self.logFile = open("/dev/tty3", "w")
  39.  
  40.     def __call__ (self, format, *args):
  41.         if args:
  42.             self.logFile.write ("* %s\n" % (format % args))
  43.         else:
  44.             self.logFile.write ("* %s\n" % format)
  45.  
  46.     def getFile (self):
  47.         return self.logFile.fileno ()
  48.             
  49. class NetworkDevice (SimpleConfigFile):
  50.     def __str__ (self):
  51.         s = ""
  52.         s = s + "DEVICE=" + self.info["DEVICE"] + "\n"
  53.         keys = self.info.keys ()
  54.         keys.sort ()
  55.         keys.remove ("DEVICE")
  56.         for key in keys:
  57.             s = s + key + "=" + self.info[key] + "\n"
  58.         return s
  59.  
  60.     def __init__ (self, dev):
  61.         self.info = { "DEVICE" : dev, "ONBOOT" : "yes" }
  62.  
  63. class Network:
  64.     def __init__ (self):
  65.         self.netdevices = {}
  66.         self.gateway = ""
  67.         self.primaryNS = ""
  68.         self.secondaryNS = ""
  69.         self.ternaryNS = ""
  70.         self.domains = []
  71.         self.readData = 0
  72.     self.isConfigured = 0
  73.         self.hostname = "localhost.localdomain"
  74.         try:
  75.             f = open ("/tmp/netinfo", "r")
  76.         except:
  77.             pass
  78.         else:
  79.             lines = f.readlines ()
  80.         f.close ()
  81.             info = {}
  82.         self.isConfigured = 1
  83.             for line in lines:
  84.                 netinf = string.splitfields (line, '=')
  85.                 info [netinf[0]] = string.strip (netinf[1])
  86.             self.netdevices [info["DEVICE"]] = NetworkDevice (info["DEVICE"])
  87.             if info.has_key ("IPADDR"):
  88.                 self.netdevices [info["DEVICE"]].set (("IPADDR", info["IPADDR"]))
  89.             if info.has_key ("NETMASK"):
  90.                 self.netdevices [info["DEVICE"]].set (("NETMASK", info["NETMASK"]))
  91.             if info.has_key ("BOOTPROTO"):
  92.                 self.netdevices [info["DEVICE"]].set (("BOOTPROTO", info["BOOTPROTO"]))
  93.             if info.has_key ("GATEWAY"):
  94.                 self.gateway = info["GATEWAY"]
  95.             if info.has_key ("DOMAIN"):
  96.                 self.domains.append(info["DOMAIN"])
  97.             if info.has_key ("HOSTNAME"):
  98.                 self.hostname = info["HOSTNAME"]
  99.             
  100.             self.readData = 1
  101.     try:
  102.         f = open ("/etc/resolv.conf", "r")
  103.     except:
  104.         pass
  105.     else:
  106.         lines = f.readlines ()
  107.         f.close ()
  108.         for line in lines:
  109.         resolv = string.split (line)
  110.         if resolv[0] == 'nameserver':
  111.             if self.primaryNS == "":
  112.             self.primaryNS = resolv[1]
  113.             elif self.secondaryNS == "":
  114.             self.secondaryNS = resolv[1]
  115.             elif self.ternaryNS == "":
  116.             self.ternaryNS = resolv[1]
  117.  
  118.     def getDevice(self, device):
  119.     return self.netdevices[device]
  120.  
  121.     def available (self):
  122.         f = open ("/proc/net/dev")
  123.         lines = f.readlines()
  124.         f.close ()
  125.         # skip first two lines, they are header
  126.         lines = lines[2:]
  127.         for line in lines:
  128.             dev = string.strip (line[0:6])
  129.             if dev != "lo" and not self.netdevices.has_key (dev):
  130.                 self.netdevices[dev] = NetworkDevice (dev)
  131.         return self.netdevices
  132.  
  133.     def lookupHostname (self):
  134.     # can't look things up if they don't exist!
  135.     if not self.hostname or self.hostname == "localhost.localdomain": return None
  136.  
  137.     if not self.isConfigured:
  138.         for dev in self.netdevices.values():
  139.         if dev.get('bootproto') == "dhcp":
  140.             self.primaryNS = isys.pumpNetDevice(dev.get('device'))
  141.             break
  142.         elif dev.get('ipaddr') and dev.get('netmask'):
  143.             isys.configNetDevice(dev.get('device'),
  144.                 dev.get('ipaddr'), dev.get('netmask'),
  145.                 self.gateway)
  146.             break
  147.  
  148.     if not self.primaryNS: return
  149.  
  150.     f = open("/etc/resolv.conf", "w")
  151.     f.write("nameserver %s\n" % self.primaryNS)
  152.     f.close()
  153.     isys.resetResolv()
  154.     isys.setResolvRetry(2)
  155.  
  156.     try:
  157.         ip = socket.gethostbyname(self.hostname)
  158.     except socket.error:
  159.         return None
  160.  
  161.     return ip
  162.  
  163.     def nameservers (self):
  164.         return [ self.primaryNS, self.secondaryNS, self.ternaryNS ]
  165.  
  166. class Password:
  167.     def __init__ (self):
  168.         self.crypt = None
  169.     self.pure = None
  170.  
  171.     def getPure(self):
  172.     return self.pure
  173.  
  174.     def set (self, password, isCrypted = 0):
  175.     if isCrypted:
  176.         self.crypt = password
  177.         self.pure = None
  178.     else:
  179.             salt = (whrandom.choice (string.letters +
  180.                                      string.digits + './') + 
  181.                     whrandom.choice (string.letters +
  182.                                      string.digits + './'))
  183.             self.crypt = crypt.crypt (password, salt)
  184.         self.pure = password
  185.  
  186.     def getCrypted(self):
  187.     return self.crypt
  188.  
  189. class Desktop (SimpleConfigFile):
  190.     def __init__ (self):
  191.         SimpleConfigFile.__init__ (self)
  192.  
  193.     def set (self, desktop):
  194.         self.info ['DESKTOP'] = desktop
  195.  
  196. class Language (SimpleConfigFile):
  197.     def __init__ (self):
  198.         self.info = {}
  199.  
  200.     if os.access("lang-table", os.R_OK):
  201.         f = open("lang-table", "r")
  202.     elif os.access("/etc/lang-table", os.R_OK):
  203.         f = open("/etc/lang-table", "r")
  204.     else:
  205.         f = open("/usr/lib/anaconda/lang-table", "r")
  206.  
  207.     lines = f.readlines ()
  208.     f.close()
  209.     self.langs = {}
  210.     self.font = {}
  211.     self.map = {}
  212.  
  213.     for line in lines:
  214.         string.strip(line)
  215.         l = string.split(line)
  216.         self.langs[l[0]] = l[4]
  217.         self.font[l[0]] = l[2]
  218.         self.map[l[0]] = l[3]
  219.     
  220.         # kickstart needs this
  221.         self.abbrevMap = {}
  222.         for (key, value) in self.langs.items ():
  223.             self.abbrevMap[value] = key
  224.  
  225.     self.setByAbbrev("en_US")
  226.  
  227.     def available (self):
  228.         return self.langs
  229.  
  230.     def setByAbbrev(self, lang):
  231.     self.set(self.abbrevMap[lang])
  232.     
  233.     def set (self, lang):
  234.         self.lang = self.langs[lang]
  235.         self.info["LANG"] = self.langs[lang]
  236.         os.environ["LANG"] = self.langs[lang]
  237.  
  238.     if self.font[lang] != "None":
  239.         self.info["SYSFONT"] = self.font[lang]
  240.         self.info["SYSFONTACM"] = self.map[lang]
  241.     else:
  242.             if self.info.has_key("SYSFONT"):
  243.                 del self.info["SYSFONT"]
  244.             if self.info.has_key("SYSFONTACM"):
  245.                 del self.info["SYSFONTACM"]
  246.  
  247.     rpm.addMacro("_install_langs", self.langs[lang]);
  248.         os.environ["LINGUAS"] = self.langs[lang]
  249.         
  250.     def get (self):
  251.     return self.lang
  252.  
  253.     def getFont (self, lang):
  254.     return self.font[lang]
  255.  
  256. class Authentication:
  257.     def __init__ (self):
  258.         self.useShadow = 1
  259.         self.useMD5 = 1
  260.         self.useNIS = 0
  261.         self.domain = ""
  262.         self.useBroadcast = 1
  263.         self.server = ""
  264.  
  265. class InstSyslog:
  266.     def __init__ (self, root, log):
  267.         self.pid = os.fork ()
  268.         if not self.pid:
  269.             if os.access ("./anaconda", os.X_OK):
  270.                 path = "./anaconda"
  271.             elif os.access ("/usr/bin/anaconda.real", os.X_OK):
  272.                 path = "/usr/bin/anaconda.real"
  273.             else:
  274.                 path = "/usr/bin/anaconda"
  275.             os.execv (path, ("syslogd", "--syslogd", root, log))
  276.  
  277.     def __del__ (self):
  278.         os.kill (self.pid, 15)
  279.         
  280. class ToDo:
  281.     def __init__(self, intf, method, rootPath, setupFilesystems = 1,
  282.          installSystem = 1, mouse = None, instClass = None, x = None,
  283.          expert = 0, serial = 0, reconfigOnly = 0, test = 0,
  284.          extraModules = []):
  285.     self.intf = intf
  286.     self.method = method
  287.     self.hdList = None
  288.     self.comps = None
  289.     self.instPath = rootPath
  290.     self.setupFilesystems = setupFilesystems
  291.     self.installSystem = installSystem
  292.         self.language = Language ()
  293.     self.serial = serial
  294.     self.fstab = None
  295.         self.reconfigOnly = reconfigOnly
  296.         self.log = LogFile (serial, reconfigOnly, test)
  297.         self.network = Network ()
  298.         self.rootpassword = Password ()
  299.         self.extraModules = extraModules
  300.         if mouse:
  301.             self.mouse = Mouse (xmouseType = mouse)
  302.         else:
  303.             self.mouse = Mouse ()
  304.         self.keyboard = Keyboard ()
  305.         self.auth = Authentication ()
  306.         self.desktop = Desktop ()
  307.         self.ddruidReadOnly = 0
  308.         self.bootdisk = 1
  309.  
  310.     # liloDevice, liloLinear, liloAppend are initialized form the
  311.     # default install class
  312.         arch = iutil.getArch ()
  313.         self.lilo = LiloConfiguration()
  314.     if arch == "sparc":
  315.         self.silo = SiloInstall (self.serial)
  316.         elif arch == "alpha":
  317.             self.milo = MiloInstall (self)
  318.     self.timezone = None
  319.         self.upgrade = 0
  320.     self.ddruidAlreadySaved = 0
  321.         self.initlevel = 3
  322.     self.expert = expert
  323.         self.progressWindow = None
  324.     self.fdDevice = None
  325.     if (not instClass):
  326.         raise TypeError, "installation class expected"
  327.         if x:
  328.             self.x = x
  329.             self.x.setMouse (self.mouse)
  330.         else:
  331.             self.x = XF86Config (mouse = self.mouse)
  332.  
  333.     # This absolutely, positively MUST BE LAST
  334.     self.setClass(instClass)
  335.  
  336.     def setFdDevice(self):
  337.     if self.fdDevice:
  338.         return
  339.     self.fdDevice = "/dev/fd0"
  340.     if iutil.getArch() == "sparc":
  341.         try:
  342.         f = open(self.fdDevice, "r")
  343.         except IOError, (errnum, msg):
  344.         if errno.errorcode[errnum] == 'ENXIO':
  345.             self.fdDevice = "/dev/fd1"
  346.         else:
  347.         f.close()
  348.  
  349.     def writeTimezone(self):
  350.     if (self.timezone):
  351.         (timezone, asUtc, asArc) = self.timezone
  352.             try:
  353.                 iutil.copyFile(self.instPath + "/usr/share/zoneinfo/" + timezone, 
  354.                                self.instPath + "/etc/localtime")
  355.             except OSError, (errno, msg):
  356.                 self.intf.messageWindow(_("Error"),
  357.                                         _("Error copying file: %s") % msg)
  358.     else:
  359.         asUtc = 0
  360.         asArc = 0
  361.  
  362.     f = open(self.instPath + "/etc/sysconfig/clock", "w")
  363.     f.write('ZONE="%s"\n' % timezone)
  364.     f.write("UTC=")
  365.     if (asUtc):
  366.         f.write("true\n")
  367.     else:
  368.         f.write("false\n")
  369.  
  370.     f.write("ARC=")
  371.     if (asArc):
  372.         f.write("true\n")
  373.     else:
  374.         f.write("false\n")
  375.     f.close()
  376.  
  377.     def getTimezoneInfo(self):
  378.     return self.timezone
  379.  
  380.     def setTimezoneInfo(self, timezone, asUtc = 0, asArc = 0):
  381.     self.timezone = (timezone, asUtc, asArc)
  382.  
  383.     def addMount(self, device, location, fsystem, reformat = 1):
  384.         if fsystem == "swap":
  385.             ufs = 0
  386.             try:
  387.                 isys.makeDevInode(device, '/tmp/' + device)
  388.             except:
  389.                 pass
  390.             try:
  391.                 ufs = isys.checkUFS ('/tmp/' + device)
  392.             except:
  393.                 pass
  394.             if not ufs:
  395.                 location = "swap"
  396.                 reformat = 1
  397.         self.mounts[location] = (device, fsystem, reformat)
  398.  
  399.     def writeLanguage(self):
  400.     f = open(self.instPath + "/etc/sysconfig/i18n", "w")
  401.     f.write(str (self.language))
  402.     f.close()
  403.  
  404.     def writeMouse(self):
  405.     if self.serial: return
  406.     f = open(self.instPath + "/etc/sysconfig/mouse", "w")
  407.     f.write(str (self.mouse))
  408.     f.close()
  409.     self.mouse.makeLink(self.instPath)
  410.  
  411.     def writeDesktop(self):
  412.     f = open(self.instPath + "/etc/sysconfig/desktop", "w")
  413.     f.write(str (self.desktop))
  414.     f.close()
  415.  
  416.     def writeKeyboard(self):
  417.     if self.serial: return
  418.     f = open(self.instPath + "/etc/sysconfig/keyboard", "w")
  419.     f.write(str (self.keyboard))
  420.     f.close()
  421.  
  422.     def needBootdisk (self):
  423.     if self.bootdisk or self.fstab.rootOnLoop(): return 1
  424.  
  425.     def makeBootdisk (self):
  426.     # this is faster then waiting on mkbootdisk to fail
  427.     self.setFdDevice()
  428.     device = self.fdDevice[5:]
  429.     file = "/tmp/floppy"
  430.     isys.makeDevInode(device, file)
  431.     try:
  432.         fd = os.open(file, os.O_RDONLY)
  433.     except:
  434.             raise RuntimeError, "boot disk creation failed"
  435.     os.close(fd)
  436.  
  437.     kernel = self.hdList['kernel']
  438.         kernelTag = "-%s-%s" % (kernel['version'], kernel['release'])
  439.  
  440.         w = self.intf.waitWindow (_("Creating"), _("Creating boot disk..."))
  441.     self.setFdDevice ()
  442.         rc = iutil.execWithRedirect("/sbin/mkbootdisk",
  443.                                     [ "/sbin/mkbootdisk",
  444.                                       "--noprompt",
  445.                                       "--device",
  446.                                       self.fdDevice,
  447.                                       kernelTag[1:] ],
  448.                                     stdout = None, stderr = None, 
  449.                     searchPath = 1, root = self.instPath)
  450.         w.pop()
  451.         if rc:
  452.             raise RuntimeError, "boot disk creation failed"
  453.  
  454.     def freeHeaderList(self):
  455.     if (self.hdList):
  456.         self.hdList = None
  457.  
  458.     def getHeaderList(self):
  459.     if (not self.hdList):
  460.         w = self.intf.waitWindow(_("Reading"),
  461.                                      _("Reading package information..."))
  462.         self.hdList = self.method.readHeaders()
  463.         w.pop()
  464.     return self.hdList
  465.  
  466.     def getCompsList(self):
  467.     if (not self.comps):
  468.         self.getHeaderList()
  469.         self.comps = self.method.readComps(self.hdList)
  470.         for comp in self.comps:
  471.         if comp.selected:
  472.             comp.select (1)
  473.     self.comps['Base'].select(1)
  474.  
  475.     self.updateInstClassComps()
  476.             
  477.     return self.comps
  478.  
  479.     def updateInstClassComps(self):
  480.     # don't load it just for this
  481.     if (not self.comps): return
  482.     group = self.instClass.getGroups()
  483.     packages = self.instClass.getPackages()
  484.     if (group == None and packages == None): return 0
  485.     for n in self.comps.keys():
  486.         self.comps[n].unselect(0)
  487.  
  488.     self.comps['Base'].select(1)
  489.     if group:
  490.         for n in group:
  491.         self.comps[n].select(1)
  492.  
  493.     if packages:
  494.         for n in packages:
  495.         self.selectPackage(n)
  496.  
  497.     if self.x.server:
  498.         self.selectPackage('XFree86-' + self.x.server)
  499.  
  500.     def selectPackage(self, package):
  501.     if not self.hdList.packages.has_key(package):
  502.         str = "package %s is not available" % (package,)
  503.         raise ValueError, str
  504.     self.hdList.packages[package].selected = 1
  505.  
  506.     def writeNetworkConfig (self):
  507.         # /etc/sysconfig/network-scripts/ifcfg-*
  508.         for dev in self.network.netdevices.values ():
  509.             device = dev.get ("device")
  510.             f = open (self.instPath + "/etc/sysconfig/network-scripts/ifcfg-" + device, "w")
  511.             f.write (str (dev))
  512.             f.close ()
  513.  
  514.         # /etc/sysconfig/network
  515.  
  516.         f = open (self.instPath + "/etc/sysconfig/network", "w")
  517.         f.write ("NETWORKING=yes\n"
  518.                  "HOSTNAME=")
  519.     if self.network.hostname:
  520.         f.write(self.network.hostname + "\n")
  521.     else:
  522.         f.write("localhost.localdomain" + "\n")
  523.     if self.network.gateway:
  524.         f.write("GATEWAY=" + self.network.gateway + "\n")
  525.         f.close ()
  526.  
  527.         # /etc/hosts
  528.         f = open (self.instPath + "/etc/hosts", "w")
  529.         localline = "127.0.0.1\t\t"
  530.  
  531.         self.log ("self.network.hostname = %s", self.network.hostname)
  532.  
  533.     ip = self.network.lookupHostname()
  534.  
  535.     # If the hostname is not resolvable, tie it to 127.0.0.1
  536.     if not ip and self.network.hostname != "localhost.localdomain":
  537.         localline = localline + self.network.hostname + " "
  538.         l = string.split(self.network.hostname, ".")
  539.         if len(l) > 1:
  540.         localline = localline + l[0] + " "
  541.                 
  542.     localline = localline + "localhost.localdomain localhost\n"
  543.         f.write (localline)
  544.  
  545.     if ip:
  546.         f.write ("%s\t\t%s\n" % (ip, self.network.hostname))
  547.  
  548.     # If the hostname was not looked up, but typed in by the user,
  549.     # domain might not be computed, so do it now.
  550.     if self.network.domains == [ "localdomain" ] or not self.network.domains:
  551.         if '.' in self.network.hostname:
  552.         # chop off everything before the leading '.'
  553.         domain = self.network.hostname[(string.find(self.network.hostname, '.') + 1):]
  554.         self.network.domains = [ domain ]
  555.  
  556.         # /etc/resolv.conf
  557.         f = open (self.instPath + "/etc/resolv.conf", "w")
  558.  
  559.     if self.network.domains != [ 'localdomain' ] and self.network.domains:
  560.         f.write ("search " + string.joinfields (self.network.domains, ' ') 
  561.             + "\n")
  562.  
  563.         for ns in self.network.nameservers ():
  564.             if ns:
  565.                 f.write ("nameserver " + ns + "\n")
  566.  
  567.         f.close ()
  568.  
  569.     def writeRootPassword (self):
  570.     pure = self.rootpassword.getPure()
  571.     if pure:
  572.         self.setPassword("root", pure)
  573.     else:
  574.             crypt = self.rootpassword.getCrypted ()
  575.             devnull = os.open("/dev/null", os.O_RDWR)
  576.  
  577.             argv = [ "/usr/sbin/usermod", "-p", crypt, "root" ]
  578.             iutil.execWithRedirect(argv[0], argv, root = self.instPath,
  579.                                    stdout = devnull, stderr = None)
  580.             os.close(devnull)
  581.  
  582.     def setupAuthentication (self):
  583.         args = [ "/usr/sbin/authconfig", "--kickstart", "--nostart" ]
  584.         if self.auth.useShadow:
  585.             args.append ("--useshadow")
  586.         if self.auth.useMD5:
  587.             args.append ("--enablemd5")
  588.         if self.auth.useNIS:
  589.             args.append ("--enablenis")
  590.             args.append ("--nisdomain")
  591.             args.append (self.auth.domain)
  592.             if not self.auth.useBroadcast:
  593.                 args.append ("--nisserver")
  594.                 args.append (self.auth.server)
  595.         iutil.execWithRedirect(args[0], args,
  596.                               stdout = None, stderr = None, searchPath = 1,
  597.                               root = self.instPath)
  598.  
  599.     def copyConfModules (self):
  600.         try:
  601.             inf = open ("/tmp/conf.modules", "r")
  602.         except:
  603.             pass
  604.         else:
  605.             out = open (self.instPath + "/etc/conf.modules", "a")
  606.             out.write (inf.read ())
  607.  
  608.     def verifyDeps (self):
  609.     self.getCompsList()
  610.         if self.upgrade:
  611.             self.fstab.mountFilesystems (self.instPath)
  612.             db = rpm.opendb (0, self.instPath)
  613.             ts = rpm.TransactionSet(self.instPath, db)
  614.         else:
  615.             ts = rpm.TransactionSet()
  616.             
  617.         self.comps['Base'].select (1)
  618.  
  619.     for p in self.hdList.packages.values ():
  620.             if p.selected:
  621.                 ts.add(p.h, (p.h, p.h[rpm.RPMTAG_NAME]))
  622.             else:
  623.                 ts.add(p.h, (p.h, p.h[rpm.RPMTAG_NAME]), "a")
  624.  
  625.     ts.order()
  626.         deps = ts.depcheck()
  627.         rc = []
  628.         if deps:
  629.             for ((name, version, release),
  630.                  (reqname, reqversion),
  631.                  flags, suggest, sense) in deps:
  632.                 if sense == rpm.RPMDEP_SENSE_REQUIRES:
  633.                     if suggest:
  634.                         (header, sugname) = suggest
  635.                     else:
  636.                         sugname = _("no suggestion")
  637.                     if not (name, sugname) in rc:
  638.                         rc.append ((name, sugname))
  639.  
  640.         del ts
  641.         if self.upgrade:
  642.             del db
  643.             self.fstab.umountFilesystems (self.instPath)            
  644.         return rc
  645.  
  646.     def selectDeps (self, deps):
  647.         if deps:
  648.             for (who, dep) in deps:
  649.                 if dep != _("no suggestion"):
  650.                     self.hdList[dep].selected = 1
  651.  
  652.     def upgradeFindRoot (self):
  653.         rootparts = []
  654.         if not self.setupFilesystems: return [ self.instPath ]
  655.         win = self.intf.waitWindow (_("Searching"),
  656.                                     _("Searching for Red Hat Linux installations..."))
  657.         
  658.         drives = self.fstab.driveList()
  659.     mdList = raid.startAllRaid(drives)
  660.  
  661.     for dev in mdList:
  662.             if fstab.isValidExt2 (dev):
  663.                 isys.makeDevInode(dev, '/tmp/' + dev)
  664.                 try:
  665.                     isys.mount('/tmp/' + dev, '/mnt/sysimage')
  666.                 except SystemError, (errno, msg):
  667.                     self.intf.messageWindow(_("Error"),
  668.                                             _("Error mounting ext2 filesystem on %s: %s") % (dev, msg))
  669.                     continue
  670.                 if os.access ('/mnt/sysimage/etc/fstab', os.R_OK):
  671.                     rootparts.append (dev)
  672.                 isys.umount('/mnt/sysimage')
  673.                 os.remove ('/tmp/' + dev)
  674.  
  675.     raid.stopAllRaid(mdList)
  676.     
  677.         for drive in drives:
  678.             isys.makeDevInode(drive, '/tmp/' + drive)
  679.             
  680.             try:
  681.                 table = _balkan.readTable ('/tmp/' + drive)
  682.             except SystemError:
  683.                 pass
  684.             else:
  685.                 for i in range (len (table)):
  686.                     (type, sector, size) = table[i]
  687.                     # 2 is ext2 in balkan speek
  688.                     if size and type == 2:
  689.             # for RAID arrays of format c0d0p1
  690.             if drive [:3] == "rd/" or drive [:4] == "ida/":
  691.                             dev = drive + 'p' + str (i + 1)
  692.             else:
  693.                             dev = drive + str (i + 1)
  694.                         isys.makeDevInode(dev, '/tmp/' + dev)
  695.                         try:
  696.                             isys.mount('/tmp/' + dev, '/mnt/sysimage')
  697.                         except SystemError, (errno, msg):
  698.                             self.intf.messageWindow(_("Error"),
  699.                                                     _("Error mounting ext2 filesystem on %s: %s") % (dev, msg))
  700.                             continue
  701.                         if os.access ('/mnt/sysimage/etc/fstab', os.R_OK):
  702.                             rootparts.append (dev)
  703.                         isys.umount('/mnt/sysimage')
  704.                         os.remove ('/tmp/' + dev)
  705.             os.remove ('/tmp/' + drive)
  706.         win.pop ()
  707.         return rootparts
  708.  
  709.     def upgradeFindPackages (self, root):
  710.         win = self.intf.waitWindow (_("Finding"),
  711.                                     _("Finding packages to upgrade..."))
  712.         if self.setupFilesystems:
  713.             isys.makeDevInode(root, '/tmp/' + root)
  714.         mdList = raid.startAllRaid(self.fstab.driveList())
  715.             isys.mount('/tmp/' + root, '/mnt/sysimage')
  716.         fstab.readFstab('/mnt/sysimage/etc/fstab', self.fstab)
  717.             isys.umount('/mnt/sysimage')        
  718.         raid.stopAllRaid(mdList)
  719.             self.fstab.mountFilesystems (self.instPath)
  720.         self.fstab.turnOnSwap(formatSwap = 0)
  721.         self.getCompsList ()
  722.     self.getHeaderList ()
  723.  
  724.         packages = rpm.findUpgradeSet (self.hdList.hdlist, self.instPath)
  725.  
  726.         # unselect all packages
  727.         for package in self.hdList.packages.values ():
  728.             package.selected = 0
  729.  
  730.         # always upgrade all packages in Base package group
  731.     self.comps['Base'].select(1)
  732.  
  733.         hasX = 0
  734.         hasgmc = 0
  735.         # turn on the packages in the upgrade set
  736.         for package in packages:
  737.             self.hdList[package[rpm.RPMTAG_NAME]].selected = 1
  738.             if package[rpm.RPMTAG_NAME] == "XFree86":
  739.                 hasX = 1
  740.             if package[rpm.RPMTAG_NAME] == "gmc":
  741.                 hasgmc = 1
  742.  
  743.         self.dbpath = "/var/lib/anaconda-rebuilddb" + str(int(time.time()))
  744.         rpm.addMacro("_rebuilddbpath", self.dbpath);
  745.  
  746.         # now, set the system clock so the timestamps will be right:
  747.         iutil.setClock (self.instPath)
  748.         
  749.         # and rebuild the database so we can run the dependency problem
  750.         # sets against the on disk db
  751.         rc = rpm.rebuilddb (self.instPath)
  752.         if rc:
  753.             self.intf.messageWindow(_("Error"),
  754.                                     _("Rebuild of RPM database failed. "
  755.                                       "You may be out of disk space?"))
  756.             raise RuntimeError, "Rebuild of RPM database failed."
  757.  
  758.         # open up the database to check dependencies
  759.         rpm.addMacro("_dbpath", self.dbpath);
  760.         db = rpm.opendb (0, self.instPath)
  761.  
  762.         # if we have X but not gmc, we need to turn on GNOME.  We only
  763.         # want to turn on packages we don't have installed already, though.
  764.         if hasX and not hasgmc:
  765.             self.log ("Has X but not GNOME")
  766.             for package in self.comps['GNOME'].items.keys ():
  767.                 rec = db.findbyname (package.name)
  768.                 if not rec:
  769.                     self.log ("GNOME: Adding %s", package)
  770.                     self.comps['GNOME'].items[package].selected = 1
  771.             
  772.         del db
  773.         self.fstab.umountFilesystems (self.instPath)
  774.  
  775.         # new package dependency fixup
  776.         deps = self.verifyDeps ()
  777.  
  778.         for (name, suggest) in deps:
  779.             self.log ("Upgrade Dependency: %s needs %s, automatically added.", name, suggest)
  780.         self.selectDeps (deps)
  781.         win.pop ()
  782.  
  783.     def rpmError (todo):
  784.         todo.instLog.write (rpm.errorString () + "\n")
  785.  
  786.     def getClass(todo):
  787.     return todo.instClass
  788.  
  789.     def setClass(todo, instClass):
  790.     todo.instClass = instClass
  791.     todo.hostname = todo.instClass.getHostname()
  792.     todo.updateInstClassComps()
  793.     ( useShadow, useMd5, useNIS, nisDomain, nisBroadcast,
  794.               nisServer) = todo.instClass.getAuthentication()
  795.         todo.auth.useShadow = useShadow
  796.         todo.auth.useMD5 = useMd5
  797.         todo.auth.useNIS = useNIS
  798.         todo.auth.domain = nisDomain
  799.         todo.auth.useBroadcast = nisBroadcast
  800.         todo.auth.server = nisServer
  801.     todo.timezone = instClass.getTimezoneInfo()
  802.     todo.bootdisk = todo.instClass.getMakeBootdisk()
  803.     todo.zeroMbr = todo.instClass.zeroMbr
  804.     (where, linear, append) = todo.instClass.getLiloInformation()
  805.  
  806.         arch = iutil.getArch ()
  807.     if arch == "i386":    
  808.         todo.lilo.setDevice(where)
  809.         todo.lilo.setLinear(linear)
  810.         todo.lilo.setAppend(append)
  811.      elif arch == "sparc":
  812.         todo.silo.setDevice(where)
  813.         todo.silo.setAppend(append)
  814.  
  815.     for (mntpoint, (dev, fstype, reformat)) in todo.instClass.fstab:
  816.         todo.addMount(dev, mntpoint, fstype, reformat)
  817.  
  818.     todo.users = []
  819.     if todo.instClass.rootPassword:
  820.         todo.rootpassword.set(todo.instClass.rootPassword,
  821.                   isCrypted = todo.instClass.rootPasswordCrypted)
  822.     if todo.instClass.language:
  823.         todo.language.setByAbbrev(todo.instClass.language)
  824.     if todo.instClass.keyboard:
  825.         todo.keyboard.set(todo.instClass.keyboard)
  826.             if todo.instClass.keyboard != "us":
  827.                 xkb = todo.keyboard.getXKB ()
  828.                 if xkb:
  829.                     apply (todo.x.setKeyboard, xkb)
  830.  
  831.     (bootProto, ip, netmask, gateway, nameserver) = \
  832.         todo.instClass.getNetwork()
  833.     if bootProto:
  834.         todo.network.gateway = gateway
  835.         todo.network.primaryNS = nameserver
  836.  
  837.         devices = todo.network.available ()
  838.         if (devices and bootProto):
  839.         list = devices.keys ()
  840.         list.sort()
  841.         dev = devices[list[0]]
  842.                 dev.set (("bootproto", bootProto))
  843.                 if bootProto == "static":
  844.                     if (ip):
  845.                         dev.set (("ipaddr", ip))
  846.                     if (netmask):
  847.                         dev.set (("netmask", netmask))
  848.  
  849.     if (todo.instClass.x):
  850.         todo.x = todo.instClass.x
  851.  
  852.     if (todo.instClass.mouse):
  853.         (type, device, emulateThreeButtons) = todo.instClass.mouse
  854.         todo.mouse.set(type, emulateThreeButtons, thedev = device)
  855.             todo.x.setMouse(todo.mouse)
  856.             
  857.         if todo.instClass.desktop:
  858.             todo.desktop.set (todo.instClass.desktop)
  859.  
  860.     def getPartitionWarningText(self):
  861.     return self.instClass.clearPartText
  862.  
  863.     # List of (accountName, fullName, password) tupes
  864.     def setUserList(todo, users):
  865.     todo.users = users
  866.  
  867.     def getUserList(todo):
  868.     return todo.users
  869.  
  870.     def setPassword(todo, account, password):
  871.     devnull = os.open("/dev/null", os.O_RDWR)
  872.  
  873.     argv = [ "/usr/bin/passwd", "--stdin", account ]
  874.     p = os.pipe()
  875.     os.write(p[1], password + "\n")
  876.     iutil.execWithRedirect(argv[0], argv, root = todo.instPath, 
  877.                    stdin = p[0], stdout = devnull)
  878.     os.close(p[0])
  879.     os.close(p[1])
  880.     os.close(devnull)
  881.  
  882.     def createAccounts(todo):
  883.     if not todo.users: return
  884.  
  885.     for (account, name, password) in todo.users:
  886.         devnull = os.open("/dev/null", os.O_RDWR)
  887.  
  888.         argv = [ "/usr/sbin/useradd", account ]
  889.         iutil.execWithRedirect(argv[0], argv, root = todo.instPath,
  890.                    stdout = devnull)
  891.  
  892.         argv = [ "/usr/bin/chfn", "-f", name, account]
  893.         iutil.execWithRedirect(argv[0], argv, root = todo.instPath,
  894.                    stdout = devnull)
  895.         
  896.         todo.setPassword(account, password)
  897.  
  898.         os.close(devnull)
  899.  
  900.     def createCdrom(self):
  901.         self.log ("making cd-rom links")
  902.     list = isys.cdromList()
  903.     count = 0
  904.     for device in list:
  905.         cdname = "cdrom"
  906.         if (count):
  907.         cdname = "%s%d" % (cdname, count)
  908.         count = count + 1
  909.  
  910.             self.log ("creating cdrom link for" + device)
  911.             try:
  912.                 os.stat(self.instPath + "/dev/" + cdname)
  913.                 self.log ("link exists, removing")
  914.                 os.unlink(self.instPath + "/dev/" + cdname)
  915.             except OSError:
  916.                 pass
  917.         os.symlink(device, self.instPath + "/dev/" + cdname)
  918.         mntpoint = "/mnt/" + cdname
  919.         self.fstab.addMount(cdname, mntpoint, "iso9660")
  920.  
  921.     def createRemovable(self, rType):
  922.     devDict = isys.floppyDriveDict()
  923.  
  924.     d = isys.hardDriveDict()
  925.     for item in d.keys():
  926.         devDict[item] = d[item]
  927.  
  928.     list = devDict.keys()
  929.     list.sort()
  930.  
  931.     count = 0
  932.     for device in list:
  933.         descript = devDict[device]
  934.         if string.find(string.upper(descript), string.upper(rType)) == -1:
  935.         continue
  936.  
  937.         self.log ("found %s disk, creating link", rType)
  938.  
  939.         try:
  940.         os.stat(self.instPath + "/dev/%s" % rType)
  941.         self.log ("link exists, removing")
  942.         os.unlink(self.instPath + "/dev/%s" % rType)
  943.         except OSError:
  944.         pass
  945.         # the 4th partition of zip/jaz disks is the one that usually
  946.         # contains the DOS filesystem.  We'll guess at using that
  947.         # one, it is a sane default.
  948.         device = device + "4";
  949.         os.symlink(device, self.instPath + "/dev/%s" % rType)
  950.         mntpoint = "/mnt/%s" % rType
  951.         self.fstab.addMount(rType, mntpoint, "auto")
  952.  
  953.     def setDefaultRunlevel (self):
  954.         inittab = open (self.instPath + '/etc/inittab', 'r')
  955.         lines = inittab.readlines ()
  956.         inittab.close ()
  957.         inittab = open (self.instPath + '/etc/inittab', 'w')        
  958.         for line in lines:
  959.             if len (line) > 3 and line[:3] == "id:":
  960.                 fields = string.split (line, ':')
  961.                 fields[1] = str (self.initlevel)
  962.                 line = string.join (fields, ':')
  963.             inittab.write (line)
  964.         inittab.close ()
  965.         
  966.     def instCallback(self, what, amount, total, h, intf):
  967.         if (what == rpm.RPMCALLBACK_TRANS_START):
  968.             # step 6 is the bulk of the transaction set
  969.             # processing time
  970.             if amount == 6:
  971.                 self.progressWindow = \
  972.                    self.intf.progressWindow (_("Processing"),
  973.                                              _("Preparing to install..."),
  974.                                              total)
  975.         if (what == rpm.RPMCALLBACK_TRANS_PROGRESS):
  976.             if self.progressWindow:
  977.                 self.progressWindow.set (amount)
  978.                 
  979.         if (what == rpm.RPMCALLBACK_TRANS_STOP and self.progressWindow):
  980.             self.progressWindow.pop ()
  981.  
  982.         if (what == rpm.RPMCALLBACK_INST_OPEN_FILE):
  983.             intf.setPackage(h)
  984.             intf.setPackageScale(0, 1)
  985.             self.instLog.write (self.modeText % (h[rpm.RPMTAG_NAME],))
  986.             self.instLog.flush ()
  987.             fn = self.method.getFilename(h)
  988.             self.rpmFD = os.open(fn, os.O_RDONLY)
  989.             fn = self.method.unlinkFilename(fn)
  990.             return self.rpmFD
  991.         elif (what == rpm.RPMCALLBACK_INST_PROGRESS):
  992.             if total:
  993.                 intf.setPackageScale(amount, total)
  994.         elif (what == rpm.RPMCALLBACK_INST_CLOSE_FILE):
  995.             os.close (self.rpmFD)
  996.             intf.completePackage(h)
  997.         else:
  998.             pass
  999.  
  1000.     def copyExtraModules(self):
  1001.     kernelVersions = []
  1002.     
  1003.     if (self.hdList.has_key('kernel-smp') and 
  1004.         self.hdList['kernel-smp'].selected):
  1005.         version = (self.hdList['kernel-smp']['version'] + "-" +
  1006.                self.hdList['kernel-smp']['release'] + "smp")
  1007.         kernelVersions.append(version)
  1008.  
  1009.     version = (self.hdList['kernel']['version'] + "-" +
  1010.            self.hdList['kernel']['release'])
  1011.     kernelVersions.append(version)
  1012.  
  1013.         for (path, subdir, name) in self.extraModules:
  1014.         pattern = ""
  1015.         names = ""
  1016.         for n in kernelVersions:
  1017.         pattern = pattern + " " + n + "/" + name + ".o"
  1018.         names = names + " " + name + ".o"
  1019.         command = ("cd %s/lib/modules; gunzip < %s/modules.cgz | " +
  1020.             "%s/bin/cpio  --quiet -iumd %s") % \
  1021.         (self.instPath, path, self.instPath, pattern)
  1022.         self.log("running: '%s'" % (command, ))
  1023.         os.system(command)
  1024.  
  1025.         for n in kernelVersions:
  1026.         fromFile = "%s/lib/modules/%s/%s.o" % (self.instPath, n, name)
  1027.         to = "%s/lib/modules/%s/%s/%s.o" % (self.instPath, n, 
  1028.                             subdir, name)
  1029.  
  1030.         if (os.access(fromFile, os.R_OK)):
  1031.             self.log("copying %s to %s" % (fromFile, to))
  1032.             os.rename(fromFile, to)
  1033.         else:
  1034.             self.log("missing DD module %s (this may be okay)" % 
  1035.                 fromFile)
  1036.  
  1037.     def depmodModules(self):
  1038.     kernelVersions = []
  1039.     
  1040.     if (self.hdList.has_key('kernel-smp') and 
  1041.         self.hdList['kernel-smp'].selected):
  1042.         version = (self.hdList['kernel-smp']['version'] + "-" +
  1043.                self.hdList['kernel-smp']['release'] + "smp")
  1044.         kernelVersions.append(version)
  1045.  
  1046.     version = (self.hdList['kernel']['version'] + "-" +
  1047.            self.hdList['kernel']['release'])
  1048.     kernelVersions.append(version)
  1049.  
  1050.         for version in kernelVersions:
  1051.         iutil.execWithRedirect ("/sbin/depmod",
  1052.                                     [ "/sbin/depmod", "-a", version ],
  1053.                                     root = self.instPath, stderr = '/dev/null')
  1054.  
  1055.     def writeConfiguration(self):
  1056.         self.writeLanguage ()
  1057.         self.writeMouse ()
  1058.         self.writeKeyboard ()
  1059.         self.writeNetworkConfig ()
  1060.         self.setupAuthentication ()
  1061.         self.writeRootPassword ()
  1062.         self.createAccounts ()
  1063.         self.writeTimezone()
  1064.  
  1065.     def doInstall(self):
  1066.     # make sure we have the header list and comps file
  1067.     self.getHeaderList()
  1068.     self.getCompsList()
  1069.  
  1070.         arch = iutil.getArch ()
  1071.  
  1072.         if arch == "alpha":
  1073.             # if were're on alpha with ARC console, set the clock
  1074.             # so that our installed files won't be in the future
  1075.             if onMILO ():
  1076.                 args = ("clock", "-A", "-s")
  1077.                 try:
  1078.                     iutil.execWithRedirect('/usr/sbin/clock', args)
  1079.                 except:
  1080.                     pass
  1081.  
  1082.     # this is NICE and LATE. It lets kickstart/server/workstation
  1083.     # installs detect this properly
  1084.     if (self.hdList.has_key('kernel-smp') and isys.smpAvailable()):
  1085.         self.hdList['kernel-smp'].selected = 1
  1086.  
  1087.     # we *always* need a kernel installed
  1088.     if (self.hdList.has_key('kernel')):
  1089.         self.hdList['kernel'].selected = 1
  1090.  
  1091.         # if NIS is configured, install ypbind and dependencies:
  1092.         if self.auth.useNIS:
  1093.             self.hdList['ypbind'].selected = 1
  1094.             self.hdList['yp-tools'].selected = 1
  1095.             self.hdList['portmap'].selected = 1
  1096.  
  1097.         if self.x.server:
  1098.             self.selectPackage ('XFree86-' + self.x.server)
  1099.  
  1100.         # make sure that all comps that include other comps are
  1101.         # selected (i.e. - recurse down the selected comps and turn
  1102.         # on the children
  1103.         if self.setupFilesystems:
  1104.             if not self.upgrade:
  1105.         if (self.ddruidAlreadySaved):
  1106.             self.fstab.makeFilesystems ()
  1107.         else:
  1108.             self.fstab.savePartitions ()
  1109.             self.fstab.makeFilesystems ()
  1110.             self.fstab.turnOnSwap()
  1111.  
  1112.             self.fstab.mountFilesystems (self.instPath)
  1113.  
  1114.         if self.upgrade and self.dbpath:
  1115.             # move the rebuilt db into place.
  1116.             os.rename (self.instPath + "/var/lib/rpm",
  1117.                        self.instPath + "/var/lib/rpm-old")
  1118.             os.rename (self.instPath + self.dbpath,
  1119.                        self.instPath + "/var/lib/rpm")
  1120.             rpm.addMacro ("_dbpath", "%{_var}/lib/rpm")
  1121.             iutil.rmrf (self.instPath + "/var/lib/rpm-old")
  1122.             # flag this so we only do it once.
  1123.             self.dbpath = None
  1124.  
  1125.         self.method.targetFstab (self.fstab)
  1126.  
  1127.     if not self.installSystem: 
  1128.         return
  1129.  
  1130.     for i in [ '/var', '/var/lib', '/var/lib/rpm', '/tmp', '/dev' ]:
  1131.         try:
  1132.             os.mkdir(self.instPath + i)
  1133.         except os.error, (errno, msg):
  1134.                 # self.intf.messageWindow("Error", "Error making directory %s: %s" % (i, msg))
  1135.                 pass
  1136.  
  1137.         # XXX in case we started out in Upgrade land, we need to
  1138.         # reset this macro to point to the right place.
  1139.         rpm.addMacro ("_dbpath", "%{_var}/lib/rpm")
  1140.     db = rpm.opendb(1, self.instPath)
  1141.     ts = rpm.TransactionSet(self.instPath, db)
  1142.  
  1143.         total = 0
  1144.     totalSize = 0
  1145.  
  1146.         if self.upgrade:
  1147.             how = "u"
  1148.         else:
  1149.             how = "i"
  1150.         
  1151.     for p in self.hdList.selected():
  1152.         ts.add(p.h, p.h, how)
  1153.         total = total + 1
  1154.         totalSize = totalSize + p.h[rpm.RPMTAG_SIZE]
  1155.  
  1156.     ts.order()
  1157.  
  1158.         if self.upgrade:
  1159.             logname = '/tmp/upgrade.log'
  1160.         else:
  1161.             logname = '/tmp/install.log'
  1162.             
  1163.     self.instLog = open(self.instPath + logname, "w+")
  1164.     syslog = InstSyslog (self.instPath, self.instPath + logname)
  1165.  
  1166.     ts.scriptFd = self.instLog.fileno ()
  1167.     # the transaction set dup()s the file descriptor and will close the
  1168.     # dup'd when we go out of scope
  1169.  
  1170.     p = self.intf.packageProgressWindow(total, totalSize)
  1171.  
  1172.         if self.upgrade:
  1173.             self.modeText = _("Upgrading %s.\n")
  1174.         else:
  1175.             self.modeText = _("Installing %s.\n")
  1176.  
  1177.         oldError = rpm.errorSetCallback (self.rpmError)
  1178.  
  1179.         problems = ts.run(0, ~rpm.RPMPROB_FILTER_DISKSPACE,
  1180.                           self.instCallback, p)
  1181.         
  1182.         if problems:
  1183.             needed = {}
  1184.             size = 12
  1185.             for (descr, (type, mount, need)) in problems:
  1186.                 idx = string.find (mount, "/mnt/sysimage")
  1187.                 if idx != -1:
  1188.                     # 13 chars in /mnt/sysimage
  1189.                     mount = mount[13:]
  1190.  
  1191.                 if needed.has_key (mount) and needed[mount] < need:
  1192.                     needed[mount] = need
  1193.                 else:
  1194.                     needed[mount] = need
  1195.                     
  1196.             probs = _("You don't appear to have enough disk space to install "
  1197.                       "the packages you've selected. You need more space on the "
  1198.                       "following filesystems:\n\n")
  1199.             probs = probs + ("%-15s %s\n") % (_("Mount Point"), _("Space Needed"))
  1200.                     
  1201.             for (mount, need) in needed.items ():
  1202.                 if need > (1024*1024):
  1203.                     need = (need + 1024 * 1024 - 1) / (1024 * 1024)
  1204.                     suffix = "M"
  1205.                 else:
  1206.                     need = (need + 1023) / 1024
  1207.                     suffix = "k"
  1208.  
  1209.                 prob = "%-15s %d %c\n" % (mount, need, suffix)
  1210.                 probs = probs + prob
  1211.                 
  1212.             self.intf.messageWindow (_("Disk Space"), probs)
  1213.  
  1214.         del ts
  1215.         del db
  1216.         self.instLog.close()
  1217.         del syslog
  1218.  
  1219.         self.fstab.umountFilesystems(self.instPath)
  1220.             
  1221.             rpm.errorSetCallback (oldError)
  1222.             return 1
  1223.  
  1224.         # This should close the RPM database so that you can
  1225.         # do RPM ops in the chroot in a %post ks script
  1226.         del ts
  1227.         del db
  1228.         rpm.errorSetCallback (oldError)
  1229.         
  1230.         self.method.filesDone ()
  1231.         
  1232.         del p
  1233.  
  1234.         self.instLog.close ()
  1235.  
  1236.         w = self.intf.waitWindow(_("Post Install"), 
  1237.                                  _("Performing post install configuration..."))
  1238.  
  1239.         if not self.upgrade:
  1240.         self.createCdrom()
  1241.         self.createRemovable("zip")
  1242.         self.createRemovable("jaz")
  1243.         self.copyExtraModules()
  1244.         self.setFdDevice()
  1245.             self.fstab.write (self.instPath, fdDevice = self.fdDevice)
  1246.             self.writeConfiguration ()
  1247.             self.writeDesktop ()
  1248.         if (self.instClass.defaultRunlevel):
  1249.         self.initlevel = self.instClass.defaultRunlevel
  1250.         self.setDefaultRunlevel ()
  1251.             
  1252.             # pcmcia is supported only on i386 at the moment
  1253.             if arch == "i386":
  1254.                 pcmcia.createPcmciaConfig(self.instPath + "/etc/sysconfig/pcmcia")
  1255.             self.copyConfModules ()
  1256.             if not self.x.skip and self.x.server:
  1257.         if self.x.server[0:3] == 'Sun':
  1258.                     try:
  1259.                         os.unlink(self.instPath + "/etc/X11/X")
  1260.                     except:
  1261.                         pass
  1262.             script = open(self.instPath + "/etc/X11/X","w")
  1263.             script.write("#!/bin/bash\n")
  1264.             script.write("exec /usr/X11R6/bin/Xs%s -fp unix/:-1 $@\n" % self.x.server[1:])
  1265.             script.close()
  1266.             os.chmod(self.instPath + "/etc/X11/X", 0755)
  1267.         else:
  1268.                     if os.access (self.instPath + "/etc/X11/X", os.R_OK):
  1269.                         os.rename (self.instPath + "/etc/X11/X",
  1270.                                    self.instPath + "/etc/X11/X.rpmsave")
  1271.             os.symlink ("../../usr/X11R6/bin/XF86_" + self.x.server,
  1272.                 self.instPath + "/etc/X11/X")
  1273.         self.x.write (self.instPath + "/etc/X11/XF86Config")
  1274.             self.setDefaultRunlevel ()
  1275.             # go ahead and depmod modules on alpha, as rtc modprobe
  1276.             # will complain loudly if we don't do it now.
  1277.             if arch == "alpha":
  1278.                 self.depmodModules()
  1279.                 
  1280.             # blah.  If we're on a serial mouse, and we have X, we need to
  1281.             # close the mouse device, then run kudzu, then open it again.
  1282.  
  1283.             # turn it off
  1284.             mousedev = None
  1285.  
  1286.             # XXX currently Bad Things (X async reply) happen when doing
  1287.             # Mouse Magic on Sparc (Mach64, specificly)
  1288.             if os.environ.has_key ("DISPLAY") and not arch == "sparc":
  1289.                 import xmouse
  1290.                 try:
  1291.                     mousedev = xmouse.get()[0]
  1292.                 except RuntimeError:
  1293.                     pass
  1294.             if mousedev:
  1295.                 try:
  1296.                     os.rename (mousedev, "/dev/disablemouse")
  1297.                 except OSError:
  1298.                     pass
  1299.                 try:
  1300.                     xmouse.reopen()
  1301.                 except RuntimeError:
  1302.                     pass
  1303.             argv = [ "/usr/sbin/kudzu", "-q" ]
  1304.         devnull = os.open("/dev/null", os.O_RDWR)
  1305.         iutil.execWithRedirect(argv[0], argv, root = self.instPath,
  1306.                    stdout = devnull)
  1307.             # turn it back on            
  1308.             if mousedev:
  1309.                 try:
  1310.                     os.rename ("/dev/disablemouse", mousedev)
  1311.                 except OSError:
  1312.                     pass
  1313.                 try:
  1314.                     xmouse.reopen()
  1315.                 except RuntimeError:
  1316.                     pass
  1317.         
  1318.         # XXX make me "not test mode"
  1319.         if self.setupFilesystems:
  1320.         if arch == "sparc":
  1321.         self.silo.install (self.fstab, self.instPath, self.hdList, 
  1322.                    self.upgrade)
  1323.         elif arch == "i386":
  1324.         self.lilo.install (self.fstab, self.instPath, self.hdList, 
  1325.                    self.upgrade)
  1326.         elif arch == "alpha":
  1327.         self.milo.write ()
  1328.         else:
  1329.         raise RuntimeError, "What kind of machine is this, anyway?!"
  1330.  
  1331.     if self.instClass.postScript:
  1332.         scriptRoot = "/"
  1333.         if self.instClass.postInChroot:
  1334.         scriptRoot = self.instPath    
  1335.  
  1336.         path = scriptRoot + "/tmp/ks-script"
  1337.  
  1338.         f = open(path, "w")
  1339.         f.write("#!/bin/sh\n\n")
  1340.         f.write(self.instClass.postScript)
  1341.         f.close()
  1342.         os.chmod(path, 0700)
  1343.  
  1344.         if self.serial:
  1345.         messages = "/tmp/ks-script.log"
  1346.         else:
  1347.         messages = "/dev/tty3"
  1348.         iutil.execWithRedirect ("/bin/sh", ["/bin/sh", 
  1349.             "/tmp/ks-script" ], stdout = messages,
  1350.             stderr = messages, root = scriptRoot)
  1351.                     
  1352.         os.unlink(path)
  1353.  
  1354.         del syslog
  1355.         
  1356.         w.pop ()
  1357.  
  1358.